/*
 * Copyright (c) 2012 Universidad Antonio de Nebrija.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Apache License v2.0
 * which accompanies this distribution, and is available at
 * http://www.apache.org/licenses/LICENSE-2.0.html
 * 
 * Contributors:
 *    Universidad Antonio de Nebrija - initial API, implementation and documentation
 */
package com.nebrija.riif.model;

import java.util.HashSet;
import java.util.Set;

/**
 * ChildComponent individual 
 * @author asanchep
 *
 */
public class ChildComponentUnit extends Component implements ChildComponent{

	/** Component implemented by this child component such as SIMPLE_CPU in "child_component SIMPLE_CPU CPU"*/
	private Component implementedComponent;
	/** Component where this child component resides*/
	private Component container;
	
	/**
	 * Creates a ChildComponent
	 * @param name name of the child component
	 * @param container Component where it resides
	 * @param component Type of component that this child belongs to, represented by the component itself
	 */
	public ChildComponentUnit(String name, Component container, Component component){
		super(name);
		this.implementedComponent=component;
		this.container=container;
	}

	@Override
	public void setProperty (String element, String property, Object value){
		// We only set a property if it existed in the component that this child is type of 
		if(!implementedComponent.existElement(element)){
			return;
		}
		// We check the RIIFProperties type of element looking for it in the type of component this child belongs to
		RIIFComponentPartType partType = implementedComponent.getType(element);
		RIIFProperties elementComponent = null;
		// Create a new element to hold the modified value for that property
		switch (partType){
			case PARAMETER:
				elementComponent = new Parameter(element);
				break;
			case CONSTANT:
				elementComponent = new Constant(element);
				break;
			case FAIL_MODE:
				elementComponent = new FailMode(element);
				break;				
			case NONE:
			default:
		}
		// If no valid type is found it exits this method without setting the property
		if(elementComponent==null){
			return;
		}
		//Set the property in the specific RIIFProperties element
		elementComponent.setProperty(property, value);
		// Add the RIIFProperties element to this ChildComponent.
		addElement(elementComponent, partType);
	}
	

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("\n-------[Child]--------\n");
		sb.append(super.toString());
		sb.append("implements ").append(implementedComponent.getName()).append("\n");
		sb.append("--------[/Child]----------\n");
		return sb.toString();
	}


	public Component getContainer() {
		return container;
	}	

	@Override
	public void resolve(RIIFElement container) {
		// Resolve all the properties of this component
		super.resolve(container);
		/*for (RIIFElement element: getElements().values()){
			element.resolve(container);
		}*/
	}

	@Override
	public void clear(RIIFElement container) {
		super.clear(container);
		/*for (RIIFElement element: getElements().values()){
			element.clear(container);
		}*/
	}

	@Override
	public RIIFElement getElement(String name) {
		RIIFElement element = super.getElement(name);
		if(element==null){
			element = implementedComponent.getElement(name);
		}
		return element;
	}
	
	public String getImplementedComponentName(){
		return implementedComponent.getName();
	}
	
	@Override
	public int getChildCount() {
		return super.getChildCount()+implementedComponent.getChildCount();
	}

	@Override
	public Set<String> getElementNames() {
		Set<String> keys = new HashSet<String>();
		keys.addAll(super.getElementNames());
		keys.addAll(implementedComponent.getElementNames());
		return keys;
	}


}
